package com.tianx.screen;

import com.tianx.exception.FactoryException;
import com.tianx.factory.Factory;
import com.tianx.util.FactoryUtil;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

/**
 * 系统窗口
 *
 * @author Bili_TianX
 */
public class SystemFrame extends JFrame {
    /**
     * 工厂
     */
    final Factory factory;
    /**
     * 数据表格
     */
    final JTable table;
    /**
     * 添加按钮
     */
    final JButton addButton;
    /**
     * 删除按钮
     */
    final JButton removeButton;
    /**
     * 修改按钮
     */
    final JButton modifyButton;
    /**
     * 查询按钮
     */
    final JButton queryButton;
    /**
     * 按钮的布局
     */
    final Box buttonLayout;
    /**
     * 窗口的布局
     */
    final Box frameLayout;
    /**
     * 行数，列数
     */
    int row, column;
    /**
     * 查询结果列表
     */
    List<Object> queryList;
    /**
     * 需要查询的值
     */
    private String queryS;
    /**
     * 需要查询的字段
     */
    private Field queryField;

    public SystemFrame(Factory factory) {
        super("管理系统");

        this.factory = factory;

        row = factory.list.size();
        column = factory.fields.size();
        table = new JTable();
        buttonLayout = Box.createHorizontalBox();
        frameLayout = Box.createVerticalBox();
        addButton = new JButton("添加" + factory.classValue);
        removeButton = new JButton("删除" + factory.classValue);
        modifyButton = new JButton("修改选中的" + factory.classValue);
        queryButton = new JButton("查询" + factory.classValue);
        modifyButton.setEnabled(false);

        setSize(800, 600);

        setLocationRelativeTo(null);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        table.getTableHeader().setReorderingAllowed(false);
        table.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                modifyButton.setEnabled(table.getSelectedRows().length == 1);
            }
        });
        updateTable();
        buttonLayout.add(addButton);
        buttonLayout.add(removeButton);
        buttonLayout.add(modifyButton);
        buttonLayout.add(queryButton);
        frameLayout.add(new JScrollPane(table));
        frameLayout.add(buttonLayout);

        addButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (!addButton.isEnabled()) return;
                try {
                    factory.add();
                    updateTable();
                } catch (FactoryException factoryException) {
                    factoryException.printStackTrace();
                }
            }
        });
        removeButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (!removeButton.isEnabled()) return;
                factory.remove();
                updateTable();
            }
        });
        modifyButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (modifyButton.isEnabled())
                    modify();
            }
        });
        queryButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (!queryButton.isEnabled()) return;
                if (queryButton.getText().equals("查询" + factory.classValue)) {
                    query();
                } else {
                    queryButton.setText("查询" + factory.classValue);
                    updateTable();
                    removeButton.setEnabled(true);
                    addButton.setEnabled(true);
                }
            }
        });
        setContentPane(frameLayout);
        setVisible(true);
    }

    /**
     * 查询对象
     */
    public void query() {
        Object[] objects = factory.fieldValue.values().toArray();
        Object type = JOptionPane.showInputDialog(this,
                "选择查询的类型",
                "修改",
                JOptionPane.PLAIN_MESSAGE,
                null,
                objects,
                objects[0]);
        if (type == null || type.equals("null")) return;
        queryS = JOptionPane.showInputDialog(this, "输入查询的值", "修改", JOptionPane.PLAIN_MESSAGE);
        if (queryS == null || queryS.equals("null")) return;
        queryField = FactoryUtil.getFieldByName(factory.fieldValue, String.valueOf(type));

        queryButton.setText("停止查询");
        removeButton.setEnabled(false);
        addButton.setEnabled(false);
        updateTable();
    }

    /**
     * 修改对象
     */
    public void modify() {
        Object[] objects = factory.fieldValue.values().toArray();
        Object o = JOptionPane.showInputDialog(this,
                "选择修改的类型",
                "修改",
                JOptionPane.PLAIN_MESSAGE,
                null,
                objects,
                objects[0]);
        if (o == null || o.equals("null")) return;
        String s = JOptionPane.showInputDialog(this, "输入修改的值", "修改", JOptionPane.PLAIN_MESSAGE);
        if (s == null || s.equals("null")) return;
        Field field = FactoryUtil.getFieldByName(factory.fieldValue, String.valueOf(o));
        try {
            assert field != null;
            factory.setMethods.get(field).invoke(factory.list.get(table.getSelectedRow()), FactoryUtil.transform(field.getType()).getConstructor(String.class).newInstance(s));
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | InstantiationException e) {
            e.printStackTrace();
        }
        updateTable();
    }

    /**
     * 关闭管理系统
     */
    @Override
    public void dispose() {
        try {
            factory.save();
        } catch (InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
        }
        System.exit(0);
    }

    /**
     * 更新数据表格
     */
    public void updateTable() {
        DefaultTableModel model;
        if (queryButton.getText().equals("停止查询")) {
            queryList = factory.query(queryField, queryS);
            row = queryList.size();
            model = new DefaultTableModel(factory.fieldToArray(), row);
            table.setModel(model);
            table.setRowSorter(new TableRowSorter<>(model));

            try {
                for (int i = 0; i < row; ++i) {
                    for (int j = 0; j < column; j++) {
                        Object o = queryList.get(i);
                        Object invoke = factory.getMethods.get(factory.fields.get(j)).invoke(o);
                        table.setValueAt(invoke, i, j);
                    }
                }
            } catch (InvocationTargetException | IllegalAccessException e) {
                e.printStackTrace();
            }
        } else {
            row = factory.list.size();
            model = new DefaultTableModel(factory.fieldToArray(), row) {
                @Override
                public boolean isCellEditable(int row, int column) {
                    return false;
                }
            };
            table.setModel(model);
            table.setRowSorter(new TableRowSorter<>(model));

            try {
                for (int i = 0; i < row; ++i) {
                    for (int j = 0; j < column; j++) {
                        Object o = factory.list.get(i);
                        Object invoke = factory.getMethods.get(factory.fields.get(j)).invoke(o);
                        table.setValueAt(invoke, i, j);
                    }
                }
            } catch (InvocationTargetException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        modifyButton.setEnabled(table.getSelectedRows().length == 1);
    }
}
